Changed signature to return success and set a GError parameter, adjusted
authorMatthias Clasen <matthiasc@src.gnome.org>
Mon, 25 Mar 2002 00:15:00 +0000 (00:15 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Mon, 25 Mar 2002 00:15:00 +0000 (00:15 +0000)
* io-png.c (setup_png_transformations): Changed signature to
return success and set a GError parameter, adjusted all callers.
Also work around a possible FPE in libpng and always check that
the new info is sane.

gdk-pixbuf/ChangeLog
gdk-pixbuf/io-png.c

index 8b1a0d6dbc80226892b791f7c3201a1667820793..e973c974629a2c7b20ad8cdef3556432ece60160 100644 (file)
@@ -1,3 +1,10 @@
+2002-03-25  Matthias Clasen  <maclas@gmx.de>
+
+       * io-png.c (setup_png_transformations): Changed signature to
+       return success and set a GError parameter, adjusted all callers.
+       Also work around a possible FPE in libpng and always check that
+       the new info is sane.
+
 2002-03-23  Matthias Clasen  <maclas@gmx.de>
 
        * io-wbmp.c (gdk_pixbuf__wbmp_image_load_increment):
index aedd0be18bdce81b9537feb333d6d8001b42d858..c287654d12d5a52d579d18f05b726b345777e433 100644 (file)
 
 \f
 
-static void
+static gboolean
 setup_png_transformations(png_structp png_read_ptr, png_infop png_info_ptr,
-                          gboolean *fatal_error_occurred,
+                          GError **error,
                           png_uint_32* width_p, png_uint_32* height_p,
                           int* color_type_p)
 {
         png_uint_32 width, height;
         int bit_depth, color_type, interlace_type, compression_type, filter_type;
-#ifndef G_DISABLE_CHECKS
         int channels;
-#endif
         
         /* Get the image info */
 
+        /* Must check bit depth, since png_get_IHDR generates an 
+           FPE on bit_depth 0.
+        */
+        bit_depth = png_get_bit_depth (png_read_ptr, png_info_ptr);
+        if (bit_depth < 1 || bit_depth > 16) {
+                g_set_error (error,
+                             GDK_PIXBUF_ERROR,
+                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+                             _("Bits per channel of PNG image is invalid."));
+                return FALSE;
+        }
         png_get_IHDR (png_read_ptr, png_info_ptr,
                       &width, &height,
                       &bit_depth,
@@ -118,29 +127,42 @@ setup_png_transformations(png_structp png_read_ptr, png_infop png_info_ptr,
         *height_p = height;
         *color_type_p = color_type;
         
-#ifndef G_DISABLE_CHECKS
         /* Check that the new info is what we want */
         
+        if (width == 0 || height == 0) {
+                g_set_error (error,
+                             GDK_PIXBUF_ERROR,
+                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+                             _("Transformed PNG has zero width or height."));
+                return FALSE;
+        }
+
         if (bit_depth != 8) {
-                g_warning("Bits per channel of transformed PNG is %d, not 8.", bit_depth);
-                *fatal_error_occurred = TRUE;
-                return;
+                g_set_error (error,
+                             GDK_PIXBUF_ERROR,
+                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+                             _("Bits per channel of transformed PNG is not 8."));
+                return FALSE;
         }
 
         if ( ! (color_type == PNG_COLOR_TYPE_RGB ||
                 color_type == PNG_COLOR_TYPE_RGB_ALPHA) ) {
-                g_warning("Transformed PNG not RGB or RGBA.");
-                *fatal_error_occurred = TRUE;
-                return;
+                g_set_error (error,
+                             GDK_PIXBUF_ERROR,
+                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+                             _("Transformed PNG not RGB or RGBA."));
+                return FALSE;
         }
 
         channels = png_get_channels(png_read_ptr, png_info_ptr);
         if ( ! (channels == 3 || channels == 4) ) {
-                g_warning("Transformed PNG has %d channels, must be 3 or 4.", channels);
-                *fatal_error_occurred = TRUE;
-                return;
+                g_set_error (error,
+                             GDK_PIXBUF_ERROR,
+                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
+                             _("Transformed PNG has unsupported number of channels, must be 3 or 4."));
+                return FALSE;
         }
-#endif
+        return TRUE;
 }
 
 static void
@@ -208,7 +230,6 @@ gdk_pixbuf__png_image_load (FILE *f, GError **error)
        png_structp png_ptr;
        png_infop info_ptr, end_info;
         png_textp text_ptr;
-        gboolean failed = FALSE;
        gint i, ctype, bpp;
        png_uint_32 w, h;
        png_bytepp volatile rows = NULL;
@@ -249,9 +270,7 @@ gdk_pixbuf__png_image_load (FILE *f, GError **error)
        png_init_io (png_ptr, f);
        png_read_info (png_ptr, info_ptr);
 
-        setup_png_transformations(png_ptr, info_ptr, &failed, &w, &h, &ctype);
-
-        if (failed) {
+        if (!setup_png_transformations(png_ptr, info_ptr, error, &w, &h, &ctype)) {
                 png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
                 return NULL;
         }
@@ -558,19 +577,16 @@ png_info_callback   (png_structp png_read_ptr,
         int i, num_texts;
         int color_type;
         gboolean have_alpha = FALSE;
-        gboolean failed = FALSE;
         
         lc = png_get_progressive_ptr(png_read_ptr);
 
         if (lc->fatal_error_occurred)
                 return;
 
-        setup_png_transformations(lc->png_read_ptr,
-                                  lc->png_info_ptr,
-                                  &failed,
-                                  &width, &height, &color_type);
-
-        if (failed) {
+        if (!setup_png_transformations(lc->png_read_ptr,
+                                       lc->png_info_ptr,
+                                       lc->error,
+                                       &width, &height, &color_type)) {
                 lc->fatal_error_occurred = TRUE;
                 return;
         }